using System;
using System.Collections.Generic;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
using System.Diagnostics;

namespace Dida
{
	public abstract class Trait
	{
		public Trait() { }
	}

	public class TraitClass
	{
		private Type mainType;

		internal TraitClass(Type mainType)
		{
			this.mainType = mainType;
		}

		public TraitInstance CreateInstance()
		{
			return (TraitInstance)Activator.CreateInstance(mainType);
		}
	}

	public abstract class TraitInstance
	{
		public TraitInstance()
		{
		}

		public abstract int GetNTraits();
		public abstract Trait GetTrait(int index);

		public T GetTrait<T>()
			where T : Trait
		{
			return (T)GetTrait(typeof(T));
		}

		public Trait GetTrait(Type traitType)
		{
			int nTraits = GetNTraits();
			for (int i = 0; i < nTraits; i++)
			{
				Trait trait = GetTrait(i);
				if (traitType.IsInstanceOfType(trait))
					return trait;
			}

			throw new Exception("Trait of type " + traitType.FullName + " not found.");
		}
	}
}